﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Xml.Linq;

namespace BackupMirthToTFS
{
    public static class BackupMirthToTfs
    {
        /// <summary>
        /// Gather all the Mirth systems to back up, check into source control
        /// </summary>
        public static void RunMirthBackups()
        {
            List<MirthBackup> mirthsToBackup = MirthBackupDAL.ListActiveMirthTargets().ToList();

            List<dynamic> mirthBackupResults = BackupMirths(mirthsToBackup).ToList();

            //get each file locally to the TFS Workspace, check out, clean for the Mirth export date in the xml, then check back into TFS
            foreach (var result in mirthBackupResults.Where(x => x.Success))
            {
                TFS.CheckOutFile(result.MirthBackup.TfsFile);
                System.IO.File.Copy(result.BackupFile, result.MirthBackup.TfsFile, true);
                RemoveDateFromXml(result.MirthBackup.TfsFile);
                TFS.CheckInFile(result.MirthBackup.TfsFile);
                MirthBackupDAL.MarkBackupAsSuccessful(result.MirthBackup.ID);
            }
        }
        /// <summary>
        /// Perform the backup of each system presented
        /// </summary>
        /// <returns>A dynamic object containing the backup success and xml file location</returns>
        public static IEnumerable<dynamic> BackupMirths(List<MirthBackup> mirthsToBackup)
        {
            //try backup
            foreach (var mirthServer in mirthsToBackup)
            {
                var result = Mirth.CallMirthSystemForFullBackup(mirthServer);
                yield return result;
            }
        }

        /// <summary>
        /// The Mirth backup contains an XML node like date value="Jan 1 2010 19:77" at the top with the timestamp that the backup was created. This method BLANKS out that node. This is important 
        /// because a node with this value will cause a new version of the file in TFS. We want to prevent this in the case of no changes on the full backup xml.
        /// Loads the file from disk, edits the Xml, then writes back to the file on disk.
        /// </summary>
        /// <param name="fileName">The Xml file full path like "c:\foo\bar.xml"</param>
        private static void RemoveDateFromXml(string fileName)
        {
            try
            {
                var sb = new StringBuilder();
                XmlWriterSettings xws = new XmlWriterSettings { OmitXmlDeclaration = true };

                using (XmlWriter xw = XmlWriter.Create(sb, xws))
                {
                    XElement root = XElement.Load(fileName);
                    root.Element("date").Value = "";
                    root.Save(xw);
                }
                File.WriteAllText(fileName, sb.ToString());

            }
            catch (Exception) { }

        }


    }

}
